<template>
  <div>
    <div class="tree-icons">
      <i v-for="i in planetData.trees.length" class="iconfont icon-dashu"></i>
    </div>
    <div class="p-info" v-if="waterC>0">
      当前水量:{{ Math.floor(user.drinkingWater) }}ml <br>
      最多能种:{{ Math.floor(settings.maxTreesCount) }}棵 <br>
      第{{ user.count }}次,喝水{{ Math.floor(waterC) }}ml <br>
    </div>
    <canvas id="c" ref="canvas"
            :style="{width:cwidth,
          height:cheight}"></canvas>

  </div>
</template>

<script>
import {Planet, Water, setCtx, setPWTC, setSettings, Utils} from '@/helper/eco'
import {mapState, mapMutations} from 'vuex';

let intervalK1;
let intervalK2;
let intervalK3;
export default {
  name: "Planet",
  data() {
    return {
      time: null,// 用于判断有间隙时间的增加次数的辅助时间节点
      timeOutEvent: 0, // 用于判断长按时间的
      waterC: 0, // 一次的水量增加值
      ctx: null,
      canvas: null,
      planet: null,
      water: [],
      trees: [],
      clouds: [],
      system: { // 固定值
        life: 2, // 树木最多死几次
        waterScale: 0.25,
        interval: 1000, // 一次的间隔
        touchMaxTime: 1000, // 检测长按事件的最长时间
        smoothFactor: 0.3,
        oneLoop: 60, // 一秒多少次
        bgOneLoop: 30 // 后台运行 一秒多少次
      },
      defaultSettings: { //参考值
        /*  系统级  */
        waterMaxR: 20, // 水滴最大的半径 单位px
        maxTreesCount: 0, //⭐️️ 树的最大棵树
        waterOfTree: 200, // 一棵树至少需要多少水才能长出来 ml

        waterColour: 'rgba(40,160,220,0.4)',
        waterLevelColour: null,
        gravity: 0.3,

        /*  用户级别  */
        touchWaterMaxML: 50, // 点击一次最大可以加多少ml的水
        touchWaterMinML: 30, // 点击一次至少可以加多少ml的水
        waterValue: 0.15

      },
      settings: {}//可修改值
    }
  },
  mounted() {
    clearInterval(intervalK3);
    //--------------------canvas，初始化ctx画笔------------------------
    this.initCtx();

    //--------------------初始化-------------------------------------

    if (this.planetData.planet === null) {
      this.planet = new Planet(
          this.canvas.width / 2,
          this.canvas.height / 2,
          100
      );
    } else this.initData();

    setPWTC(this.planet, this.water, this.trees, this.clouds);

    this.initSettings();

    //--------------------绑定点击事件----------------------------------
    this.bandingTouch();

    //--------------------循环事件-------------------------------------
    intervalK1 = setInterval(this.Loop, 1000 / this.system.oneLoop);
    intervalK2 = setInterval(this.savePlanet, 5000);

  },
  destroyed() {
    clearInterval(intervalK1);
    clearInterval(intervalK2);
    this.savePlanet();

    intervalK3 = setInterval(this.backgroundLoop, 1000 / this.system.bgOneLoop);
  },
  methods: {
    ...mapMutations(['setPlanet', 'canDrinkWater']),
    reloadSettings() {
      this.initSettings();
      this.bandingTouch();
    },
    savePlanet() {
      this.setPlanet({
        planet: this.planet,
        trees: this.trees,
        water: this.water,
        clouds: this.clouds
      });
    },
    initCtx() {
      //--------------------canvas-------------------------------------
      this.canvas = this.$refs.canvas;
      this.ctx = this.canvas.getContext('2d')
      this.canvas.width = this.cwidth;
      this.canvas.height = this.cheight;
      //--------------------初始化ctx画笔-------------------------------------
      this.ctx.circle = function (x, y, r, c) {
        this.beginPath();
        this.arc(x, y, r, 0, Math.PI * 2);
        this.fillStyle = c;
        this.fill();
      };
      this.ctx.shape = function (points, c) {

        this.beginPath();

        this.moveTo(points[0].x, points[0].y);

        for (let i = 1, l = points.length; i < l; i++)
          this.lineTo(points[i].x, points[i].y)

        this.closePath();

        this.fillStyle = c;
        this.fill();
      };
      this.ctx.clear = function () {
        this.fillStyle = '#f9f9f9';
        this.fillRect(0, 0, this.canvas.width, this.canvas.height);
      };
      setCtx(this.ctx);
    },
    initSettings() {
      /* 自定义优先级大于默认值 */
      this.settings = {
        ...this.defaultSettings, // 加载默认配置
        ...this.activeCup.settings // 加载自定义配置
      }

      /*    系统值不能修改    */
      this.settings.waterLevelColour = this.settings.waterColour;
      this.settings.waterOfTree = this.user.drinkingTarget / 20;
      this.settings.maxTreesCount = this.user.drinkingWater / this.settings.waterOfTree;
      this.settings.maxTreesCount = this.settings.maxTreesCount > 20 ? 20 : this.settings.maxTreesCount;

      if (this.settings.touchWaterMaxML > 50) {
        this.settings.waterMaxR += Math.floor((this.settings.touchWaterMaxML - 50) * this.system.waterScale);
        if (this.settings.waterMaxR > 3 * this.planet.r / 4) {
          this.settings.waterMaxR = 3 * this.planet.r / 4;
        }
      }

      setSettings(this.settings);
    },
    touchstart(evt) {
      evt.preventDefault();
      this.timeOutEvent = evt.timeStamp;
    },
    touchend(evt) {

      // =================== 计算 v ===================
      let duration = evt.timeStamp - this.timeOutEvent;
      let t_per = (duration / this.system.touchMaxTime);
      let v = t_per * this.settings.touchWaterMaxML;
      if (v < this.settings.touchWaterMinML) { // 匹配最小值
        if (this.globalSettings.smooth.value) {
          v = (Math.random() + this.system.smoothFactor) * this.settings.touchWaterMinML;
        } else {
          v = this.settings.touchWaterMinML;
        }
        t_per = v / this.settings.touchWaterMaxML;
      } else if (v >= this.settings.touchWaterMaxML) {
        v = this.settings.touchWaterMaxML;
        t_per = 1;
      }

      let rect = this.canvas.getBoundingClientRect();
      let x = evt.changedTouches[0].clientX - rect.left;
      let y = evt.changedTouches[0].clientY - rect.top;
      let r = this.settings.waterMaxR * t_per;

      let dist = Utils.distance({x, y}, this.planet);
      if ((dist + r) <= this.planet.r) return;


      let curTime = new Date().getTime();
      let canDrink = curTime - this.time > this.system.interval;
      this.time = curTime;
      if (canDrink) {
        if (this.user.count !== 0) {
          this.waterC = 0;
        }
        this.waterC += v;
        this.canDrinkWater({v, do: true});
      } else {
        this.waterC += v;
        this.canDrinkWater({v, do: false});
      }
      this.activeCup.drinkWater += v;

      this.settings.maxTreesCount = this.user.drinkingWater / this.settings.waterOfTree;
      this.settings.maxTreesCount = this.settings.maxTreesCount > 20 ? 20 : this.settings.maxTreesCount;

      this.water.push(
          new Water(x, y, r, false, this.settings.gravity, this.settings.waterColour, this.settings.waterValue));
    },
    bandingTouch() {
      this.$el.removeEventListener('touchstart', this.touchstart);
      this.$el.removeEventListener('touchend', this.touchend);
      //--------------------绑定点击事件-------------------------------------
      this.$el.addEventListener('touchstart', this.touchstart)
      this.$el.addEventListener('touchend', this.touchend)
    },
    initData() {
      this.count = this.user.count;
      this.planet = this.planetData.planet;
      this.trees = this.planetData.trees;
      this.water = this.planetData.water;
      this.clouds = this.planetData.clouds;
    },
    Loop() {
      this.ctx.clear();

      let i = this.water.length;
      while (i--) {
        if (this.water[i].update()) this.water[i].draw();
      }

      this.planet.update();
      this.planet.draw();

      i = this.trees.length;
      while (i--) {
        this.trees[i].update();
        if (this.trees[i].dead_count > this.system.life) this.trees.splice(this.trees[i], 1);
        this.trees[i].draw();
      }

      i = this.clouds.length;
      while (i--) {
        if (this.clouds[i].update()) this.clouds[i].draw();
      }
    },
    backgroundLoop() {
      let i = this.water.length;
      while (i--) {
        this.water[i].update();
      }

      this.planet.update();

      i = this.trees.length;
      while (i--) {
        this.trees[i].update();
        this.trees[i].backgroundDraw();
      }

      i = this.clouds.length;
      while (i--) {
        this.clouds[i].update();
      }
    },
  },
  computed: {
    ...mapState(['planetData', 'user', 'activeCup', 'globalSettings']),
    cwidth() {
      return document.documentElement.clientWidth;
    },
    cheight() {
      return document.documentElement.clientHeight;
    }
  },
  watch: {
    "$store.state.activeCup": {
      handler(newV, oldV) {
        this.reloadSettings();
      }
    }
  }
}
</script>

<style>
.p-info {
  font-size: 10px;
  position: absolute;
  border-radius: 0 0 20px 20px;
  top: 19px;
}

.tree-icons {
  position: absolute;
  top: 0;
  left: 0;
  line-height: 10px;
}

#c {
  margin: 0 auto;
  display: block;
  background: #f9f9f9;
}

.iconfont.icon-dashu {
  font-size: 10px;
  color: #99da4e;
}

</style>